package com.aizuda.boot.modules.flw.flow;

import com.aizuda.boot.modules.business.contract.util.AuthUtil;
import com.aizuda.boot.modules.business.permission.service.RolePermissionService;
import com.aizuda.boot.modules.system.service.ISysUserDepartmentService;
import com.aizuda.boot.modules.system.service.ISysUserRoleService;
import com.aizuda.bpm.engine.TaskAccessStrategy;
import com.aizuda.bpm.engine.assist.Assert;
import com.aizuda.bpm.engine.assist.ObjectUtils;
import com.aizuda.bpm.engine.core.FlowCreator;
import com.aizuda.bpm.engine.entity.FlwTaskActor;
import com.aizuda.bpm.mybatisplus.mapper.FlwTaskActorMapper;
import com.aizuda.core.api.ApiAssert;
import com.aizuda.service.spring.SpringHelper;
import com.aizuda.service.web.UserSession;
import jakarta.annotation.Resource;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.Objects;
import java.util.Optional;

@Component
public class FlowTaskAccessStrategy implements TaskAccessStrategy {

    @Resource
    private FlwTaskActorMapper flwTaskActorMapper;

    @Override
    public FlwTaskActor getAllowedFlwTaskActor(Long taskId, FlowCreator flowCreator, List<FlwTaskActor> taskActors) {
        if (Boolean.TRUE.equals(FlowHelper.getTaskIntervene())) {
            FlowHelper.removeTaskIntervene();
            if (AuthUtil.isSuperAdmin()) {
                // 从FlowDataTransfer中获取干预操作标识
                // 检查是否有权限进行干预操作
                List<FlwTaskActor> flwTaskActors = flwTaskActorMapper.selectListByTaskId(taskId);
                if (flwTaskActors.size() == 1) {
                    return flwTaskActors.get(0);
                } else if (flwTaskActors.size() > 1) {
                    // 如果有多条记录，保留第一条，删除其他记录
                    FlwTaskActor keepRecord = flwTaskActors.get(0);
                    for (int i = 1; i < flwTaskActors.size(); i++) {
                        flwTaskActorMapper.deleteById(flwTaskActors.get(i).getId());
                    }
                    return keepRecord;
                }
            }
            ApiAssert.fail("Not authorized to perform this task");
        }
        Optional<FlwTaskActor> taskActorOpt = taskActors.stream().filter(t -> Objects.equals(t.getActorId(), flowCreator.getCreateId())).findFirst();
        Assert.isTrue(!taskActorOpt.isPresent(), "Not authorized to perform this task");
        return taskActorOpt.get();
    }

    @Override
    public FlwTaskActor isAllowed(String userId, List<FlwTaskActor> taskActors) {
        if (null == userId || ObjectUtils.isEmpty(taskActors)) {
            return null;
        }

        if (Boolean.TRUE.equals(FlowHelper.getTaskIntervene())) {
            FlowHelper.removeTaskIntervene();
            if (AuthUtil.isSuperAdmin()) {
                // 从FlowDataTransfer中获取干预操作标识
                // 判断是否有权限审批别人的流程
                UserSession loginInfo = UserSession.getLoginInfo();
                FlwTaskActor actor = new FlwTaskActor();
                actor.setActorId(userId);
                actor.setActorName(loginInfo.getUsername());
                actor.setActorType(0); // 0表示用户类型
                return actor;
            }
            return null;
        }

        // 优先匹配用户参与者情况
        Optional<FlwTaskActor> ftaOpt = taskActors.stream().filter(t ->
                Objects.equals(0, t.getActorType()) && Objects.equals(t.getActorId(), userId)).findFirst();
        if (ftaOpt.isPresent()) {
            return ftaOpt.get();
        }

        FlwTaskActor flwTaskActor = taskActors.get(0);
        if (Objects.equals(flwTaskActor.getActorType(), 1)) {
            // 角色
            ISysUserRoleService sysUserRoleService = SpringHelper.getBean(ISysUserRoleService.class);
            return contains(taskActors, sysUserRoleService.listRoleIdsByUserId(Long.valueOf(userId)));
        } else if (Objects.equals(flwTaskActor.getActorType(), 2)) {
            // 部门
            ISysUserDepartmentService sysUserDepartmentService = SpringHelper.getBean(ISysUserDepartmentService.class);
            return contains(taskActors, sysUserDepartmentService.listDepartmentIdsByUserId(Long.valueOf(userId)));
        }

        // 无匹配参与者
        return null;
    }


    private FlwTaskActor contains(List<FlwTaskActor> taskActors, List<Long> ids) {
        if (CollectionUtils.isEmpty(ids)) {
            return null;
        }
        return taskActors.stream().filter(t -> ids.contains(Long.valueOf(t.getActorId()))).findFirst().orElse(null);
    }
}
